package org.zjvis.datascience.web.shiro;

import java.util.Set;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.zjvis.datascience.common.dto.user.UserDTO;
import org.zjvis.datascience.common.exception.DataScienceException;
import org.zjvis.datascience.common.shiro.UsernamePasswordCaptchaToken;
import org.zjvis.datascience.service.UserService;
import cn.hutool.crypto.digest.BCrypt;
import lombok.extern.slf4j.Slf4j;


/**
 * @description : 权限检查类
 * @date 2021-08-05
 */
@Component
@Slf4j
public class Realm extends AuthorizingRealm {
    private final static Logger logger = LoggerFactory.getLogger("Realm");

    @Autowired
    private UserService userService;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordCaptchaToken;
    }

    /**
     * 权限
     *
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        UserDTO user = (UserDTO) principals.getPrimaryPrincipal();
        Set<String> list = userService.queryPermissionByUserId(user.getId());
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(list);
        return info;
    }

    /**
     * 登录验证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authToken)
            throws AuthenticationException {
        UsernamePasswordCaptchaToken token = (UsernamePasswordCaptchaToken) authToken;
        String password = new String(token.getPassword());
        String username = token.getUsername();
        UserDTO userDTO = userService.queryByName(username);

        if (userDTO == null) {
            return null;
        }
        try {
            if (!BCrypt.checkpw(password, userDTO.getPassword())) {
                return null;
            }
            return new SimpleAuthenticationInfo(userDTO, password, "");
        } catch (Exception e) {
            logger.error("Realm doGetAuthenticationInfo error:{}", e);
            throw new DataScienceException(e.getMessage());
        }
    }

}

